import yfinance as yf
import pandas as pd
from datetime import datetime
def download_all_call_options_data(symbol):
ticker = yf.Ticker(symbol)
expiration_dates = ticker.options
all_call_options_data = pd.DataFrame() # DataFrame to store all call option data
for exp_date in expiration_dates:
option_chain_data = ticker.option_chain(exp_date)
calls = option_chain_data.calls
# Add a column to indicate the expiration date for this call option DataFrame
calls['ExpirationDate'] = exp_date
# Concatenate this expiration date's call option DataFrame to the all_call_options_data DataFrame
all_call_options_data = pd.concat([all_call_options_data, calls], ignore_index=True)
return all_call_options_data
symbol = "AAPL" # Replace this with the desired stock symbol
options_data = download_all_call_options_data(symbol)
options_data
| contractSymbol | lastTradeDate | strike | lastPrice | bid | ask | change | percentChange | volume | openInterest | impliedVolatility | inTheMoney | contractSize | currency | ExpirationDate | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | AAPL230811C00050000 | 2023-07-11 13:44:51+00:00 | 50.0 | 138.21 | 131.20 | 132.45 | 0.000000 | 0.000000 | NaN | 0 | 4.968754 | True | REGULAR | USD | 2023-08-11 |
| 1 | AAPL230811C00080000 | 2023-07-18 19:50:00+00:00 | 80.0 | 114.55 | 101.60 | 102.80 | 0.000000 | 0.000000 | 1.0 | 1 | 2.898440 | True | REGULAR | USD | 2023-08-11 |
| 2 | AAPL230811C00085000 | 2023-07-26 14:23:23+00:00 | 85.0 | 108.99 | 96.35 | 98.35 | 0.000000 | 0.000000 | NaN | 1 | 2.923831 | True | REGULAR | USD | 2023-08-11 |
| 3 | AAPL230811C00095000 | 2023-07-19 17:26:07+00:00 | 95.0 | 99.95 | 86.35 | 88.75 | 0.000000 | 0.000000 | 1.0 | 1 | 2.728519 | True | REGULAR | USD | 2023-08-11 |
| 4 | AAPL230811C00100000 | 2023-08-04 14:09:41+00:00 | 100.0 | 85.17 | 81.35 | 83.80 | 85.170000 | NaN | 3.0 | 0 | 2.556644 | True | REGULAR | USD | 2023-08-11 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 819 | AAPL251219C00270000 | 2023-08-04 19:11:01+00:00 | 270.0 | 8.60 | 8.25 | 8.65 | -2.370000 | -21.604374 | 5.0 | 463 | 0.273246 | False | REGULAR | USD | 2025-12-19 |
| 820 | AAPL251219C00280000 | 2023-08-04 19:59:11+00:00 | 280.0 | 6.90 | 6.75 | 7.20 | -2.249999 | -24.590160 | 168.0 | 1234 | 0.269752 | False | REGULAR | USD | 2025-12-19 |
| 821 | AAPL251219C00290000 | 2023-08-04 19:57:55+00:00 | 290.0 | 5.85 | 5.45 | 5.85 | -1.650000 | -22.000002 | 11.0 | 588 | 0.264854 | False | REGULAR | USD | 2025-12-19 |
| 822 | AAPL251219C00300000 | 2023-08-04 19:54:37+00:00 | 300.0 | 4.75 | 4.60 | 4.80 | -1.350000 | -22.131147 | 385.0 | 4941 | 0.261482 | False | REGULAR | USD | 2025-12-19 |
| 823 | AAPL251219C00310000 | 2023-08-04 19:57:48+00:00 | 310.0 | 3.82 | 3.70 | 3.85 | -1.280000 | -25.098038 | 162.0 | 3304 | 0.257118 | False | REGULAR | USD | 2025-12-19 |
824 rows × 15 columns
yoyo = pd.DataFrame({'strike': options_data.strike, 'impliedVolatility': options_data.impliedVolatility, 'ExpirationDate': options_data.ExpirationDate})
import plotly.express as px
fig = px.scatter_3d(yoyo, x='strike', y='ExpirationDate', z='impliedVolatility',
color='impliedVolatility')
# Customize the layout
fig.update_layout(
title='3D Scatter Plot of Implied Volatility',
scene=dict(
xaxis_title='Strike',
yaxis_title='Expiration Date',
zaxis_title='Implied Volatility'
), width=1000, height=900,
margin=dict(l=0, r=0, b=0, t=40), # Adjust margins if needed
# Add more layout customizations here
)
fig.show()
Esempio di come la volatilità implicita è correlata con il prezzo delle opzioni
symbol = "AAPL"
ticker = yf.Ticker(symbol)
ticker.options[6]
'2023-09-22'
exp_date = ticker.options[6]
options_chain = ticker.option_chain(exp_date)
calls = options_chain.calls
import pandas as pd
df= pd.DataFrame({'strike':calls.strike, 'impliedVolatility': calls.impliedVolatility, 'lastPrice': calls.lastPrice})
df
| strike | impliedVolatility | lastPrice | |
|---|---|---|---|
| 0 | 130.0 | 0.608158 | 53.31 |
| 1 | 150.0 | 0.462530 | 36.41 |
| 2 | 155.0 | 0.440435 | 29.77 |
| 3 | 160.0 | 0.398199 | 26.50 |
| 4 | 165.0 | 0.349250 | 19.52 |
| 5 | 170.0 | 0.310432 | 15.10 |
| 6 | 175.0 | 0.275642 | 11.15 |
| 7 | 180.0 | 0.256233 | 7.60 |
| 8 | 185.0 | 0.238899 | 4.90 |
| 9 | 190.0 | 0.227486 | 2.91 |
| 10 | 195.0 | 0.229622 | 1.62 |
| 11 | 200.0 | 0.219734 | 0.86 |
| 12 | 205.0 | 0.222176 | 0.47 |
| 13 | 210.0 | 0.229012 | 0.27 |
| 14 | 215.0 | 0.241707 | 0.17 |
| 15 | 220.0 | 0.255867 | 0.13 |
| 16 | 225.0 | 0.271492 | 0.10 |
| 17 | 230.0 | 0.287117 | 0.08 |
| 18 | 235.0 | 0.299812 | 0.06 |
| 19 | 240.0 | 0.320319 | 0.05 |
| 20 | 245.0 | 0.334968 | 0.04 |
| 21 | 255.0 | 0.365241 | 0.03 |
| 22 | 265.0 | 0.402350 | 0.02 |
import matplotlib.pyplot as plt
%matplotlib inline
fig, ax1 = plt.subplots(figsize=(18, 8), dpi=100)
ax1.set_ylabel('Option Price', color="black")
ax1.plot(df.lastPrice, color="black")
ax1.tick_params(axis='y', labelcolor="black")
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.set_ylabel('Implied Volatility', color="black") # we already handled the x-label with ax1
ax2.plot(df.impliedVolatility, color="blue")
ax2.tick_params(axis='y', labelcolor="black")
fig.tight_layout() # otherwise, the right y-label is slightly clipped
plt.show()
s0 = yf.download(symbol, period="max", interval="1d")["Close"]
S = s0[-1]
S
[*********************100%***********************] 1 of 1 completed
181.99000549316406